package com.zyl.factory;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * @version v1.0
 * @ProjectName: env_gather
 * @Package: com.zyl.factory
 * @ClassName: FactoryInstance
 * @Description TODO(抽象工厂的实现类)
 * @Author 翟玉龙
 * @Date 2024/10/24-15:17
 */
public class FactoryInstance implements FactoryInstancePlus {
    private static final Map<String, Object> INSTANCE_MAP = new HashMap<>();

    private static FactoryInstance instance;

    private FactoryInstance() {

    }

    static {
        try(InputStream in = FactoryInstancePlus.class.getClassLoader().getResourceAsStream("bean-server.properties")) {
            Properties prop = new Properties();
            prop.load(in);
            for(Map.Entry<Object, Object> entry : prop.entrySet()) {
                String className = (String) entry.getKey();
                String classPath = (String) entry.getValue();
                Object o = Class.forName(classPath).getConstructor().newInstance();
                INSTANCE_MAP.put(className, o);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public static FactoryInstance init() {
        synchronized (FactoryInstance.class) {
            if (instance == null) {
                instance = new FactoryInstance();
            }
        }
        return instance;
    }

    @Override
    public Object getInstance(String className) {
        return INSTANCE_MAP.get(className);
    }

    @Override
    public <T> T getInstance(String className, Class<T> tClass) {
        Object o = INSTANCE_MAP.get(className);
        return tClass.isInstance(o) ? tClass.cast(o) : null;
    }

    @Override
    public Object getLazyInstance(String className, String classPath) {
        if (!INSTANCE_MAP.containsKey(className)) {
            try {
                Class<?> clazz = Class.forName(classPath);
                Object instance = clazz.getDeclaredConstructor().newInstance();
                INSTANCE_MAP.put(className, instance);
            } catch (Exception e) {
                throw new RuntimeException("Failed to create lazy instance for " + className, e);
            }
        }
        return INSTANCE_MAP.get(className);
    }
}
